import { getApi } from '@/requestConfig';
import { authorizeRenewOSS } from '@/services/api/api-aliyun';
import { getToken } from '@/utils/token';
import { InboxOutlined } from '@ant-design/icons';
import OSS from 'ali-oss';
import { message, Upload } from 'antd';
import { UploadChangeParam, UploadFile } from 'antd/es/upload/interface';
import moment from 'moment';
import { useState } from 'react';
import { useModel } from 'umi';
import style from './UploadDragger.less';

interface UploadDraggerProps {
  access: {
    isPicture: boolean;
    isVideo: boolean;
    isOffice: boolean;
    isOther: boolean;
  };
  url?: string;
  maxCount: number;
  value?: UploadFile[];
  onChange?(value: UploadFile[]): void;
  onPreview(file: UploadFile | undefined): void;
}

const UploadDragger: React.FC<UploadDraggerProps> = ({
  access,
  url,
  maxCount,
  value,
  onChange,
  onPreview,
}) => {
  const { initialState, setInitialState } = useModel('@@initialState');

  const [preview, setPreviewState] = useState<UploadFile>();

  const [showDragger, setShowDraggerState] = useState<boolean>(true);

  const customRequest = async (options: any) => {

    if (options.file !== undefined && options.file.name !== undefined) {
      const fileType = options.file.name.split('.').pop().toLocaleLowerCase(); //小写

      if (fileType === undefined || fileType === null || fileType === '') {
        message.error('文件名出错');
        options.onError('文件名出错', options.file);
        return;
      }

      if (
        access.isPicture &&
        (fileType === 'png' ||
          fileType === 'jpg' ||
          fileType === 'jpeg' ||
          fileType === 'bmp' ||
          fileType === 'webp ')
      ) {
        const isLt20MB = options.file.size / 1024 / 1024 < 20;

        if (!isLt20MB) {
          message.error('图片大小不超过 20 MB');
          options.onError('图片大小不超过 20 MB', options.file);
          return;
        }
      } else if (
        access.isVideo &&
        (fileType === 'mp3' ||
          fileType === 'mp4' ||
          fileType === 'wav' ||
          fileType === 'flv' ||
          fileType === 'avi' ||
          fileType === 'mov' ||
          fileType === 'rm' ||
          fileType === 'webm' ||
          fileType === 'ts' ||
          fileType === 'mkv' ||
          fileType === 'mpeg' ||
          fileType === 'ogg' ||
          fileType === 'mpg' ||
          fileType === 'rmvb' ||
          fileType === 'wmv' ||
          fileType === '3gp' ||
          fileType === 'swf ')
      ) {
        const isLt5GB = options.file.size / 1024 / 1024 / 1024 < 5;
        if (!isLt5GB) {
          message.error('文件大小不超过 5 GB');
          options.onError('文件大小不超过 5 GB', options.file);
          return;
        }
      } else if (
        access.isOffice &&
        //Office 办公文档
        (fileType === 'doc' ||
          fileType === 'docx' ||
          fileType === 'xls' ||
          fileType === 'xlsx' ||
          fileType === 'xlsm' ||
          fileType === 'ppt' ||
          fileType === 'pptx' ||
          fileType === 'csv' ||
          fileType === 'tsv' ||
          fileType === 'dotm' ||
          fileType === 'xlt' ||
          fileType === 'xltm' ||
          fileType === 'dot' ||
          fileType === 'dotx' ||
          fileType === 'xlam' ||
          fileType === 'xla' ||
          //国产 WPS Office 办公文档
          fileType === 'wps' ||
          fileType === 'wpt' ||
          fileType === 'dps' ||
          fileType === 'dpt' ||
          fileType === 'et' ||
          fileType === 'ett' ||
          //OpenOffice、LibreOffice 办公文档
          fileType === 'odt' ||
          fileType === 'ods' ||
          fileType === 'ots' ||
          fileType === 'odp' ||
          fileType === 'otp' ||
          fileType === 'six' ||
          fileType === 'ott' ||
          fileType === 'fodt' ||
          fileType === 'fods' ||
          //支持 pdf ,ofd, rtf 等文档
          fileType === 'pdf' ||
          fileType === 'ofd' ||
          fileType === 'rtf' ||
          fileType === 'psd' ||
          //Visio 流程图文件
          fileType === 'vsd' ||
          fileType === 'vsdx' ||
          //支持 bpmn 工作流文件
          fileType === 'bpmn')
      ) {
        const isLt5GB = options.file.size / 1024 / 1024 / 1024 < 5;
        if (!isLt5GB) {
          message.error('文件大小不超过 5 GB');
          options.onError('文件大小不超过 5 GB', options.file);
          return;
        }
      } else if (access.isOther && (fileType === 'rar' || fileType === 'zip')) {
        const isLt5GB = options.file.size / 1024 / 1024 / 1024 < 5;
        if (!isLt5GB) {
          message.error('文件大小不超过 5 GB');
          options.onError('文件大小不超过 5 GB', options.file);
          return;
        }
      } else {
        message.error('不支持该格式文件');
        options.onError('不支持该格式文件', options.file);
        return;
      }

      const response = await authorizeRenewOSS();

      if (response.code === 0) {
        const headers = {
          'Content-Disposition': 'attachment;',
          'Content-Type': options.file.type,
        };

        const multipartUploadOptions = {
          callback: {
            url: getApi() + url,
            body: response.data.callbackBody,
            contentType: response.data.callbackContentType,
            satoken: getToken(),
          },
          progress: (p: number, cpt: any, res: any) => {
            options.onProgress({ percent: Math.round(p * 100).toFixed(2) }, options.file);
          },
          headers,
        };

        const OSSData = {
          accessKeyId: response.data.accessKeyId,
          accessKeySecret: response.data.accessKeySecret,
          stsToken: response.data.securityToken,
          region: response.data.callbackRegion,
          bucket: response.data.callbackBucket,
        };

        const client = new OSS({
          region: OSSData.region,
          accessKeyId: OSSData.accessKeyId,
          accessKeySecret: OSSData.accessKeySecret,
          stsToken: OSSData.stsToken,
          refreshSTSToken: async () => {
            const response = await authorizeRenewOSS();
            return {
              accessKeyId: response.data.accessKeyId,
              accessKeySecret: response.data.accessKeySecret,
              stsToken: response.data.securityToken,
            };
          },
          refreshSTSTokenInterval: 300000,
          bucket: OSSData.bucket,
        });

        client
          .multipartUpload(
            `${initialState?.currentUser?.organizationName}/assess/render/${moment().format(
              'YYYY-MM-DD',
            )}/${options.file.name}`,
            options.file,
            multipartUploadOptions,
          )
          .then((response: any) => {
            if (response.data.code === 0) {
              options.onSuccess(response.data, options.file);
            } else {
              options.onError(response.data.msg, options.file);
            }
          })
          .catch((e: any) => {
            options.onError('发生错误', options.file);
          });
      }
    } else {
      message.error('文件出错啦');
      options.onError('文件出错啦', options.file);
      return;
    }
  };

  const handlePreview = async (file: UploadFile) => {
    // onLoading(true);
    if (file?.status === 'done' && file.response && file.response?.data?.id) {
      onPreview(file);
      setPreviewState(file);
    } else {
      message.warning('暂无预览数据');
    }

    // setTimeout(() => {
    //   onLoading(false);
    // }, 180);
  };

  const handleChange = (info: UploadChangeParam) => {
    if (onChange) {
      onChange(info.fileList);
    }
    setShowDraggerState(info.fileList.length < maxCount);
  };

  const handleRemove = async (file: UploadFile) => {
  };

  return (
    <Upload.Dragger
      listType="picture"
      multiple
      fileList={value}
      customRequest={customRequest}
      onPreview={handlePreview}
      onChange={handleChange}
      maxCount={maxCount}
      className={showDragger ? '' : style['ant-upload-wrapper']}
      // className={style['ant-upload-wrapper']}
      // className={style['ant-upload-wrapper']}
      onRemove={handleRemove}
    >
      <p className="ant-upload-drag-icon">
        <InboxOutlined />
      </p>
      <p className="ant-upload-text">单击或拖动文件到该区域进行上传</p>
      <p className="ant-upload-hint">
        支持以下类型文件：{access.isPicture ? '图片、' : ''}
        {access.isVideo ? '音视频、' : ''}
        {access.isOffice ? '办公文档、' : ''}
        {access.isOther ? '压缩包' : ''}
      </p>
    </Upload.Dragger>
  );
};

export default UploadDragger;
